Spring Security একটি শক্তিশালী ফিল্টার চেইন ব্যবহার করে যা HTTP রিকোয়েস্টগুলোর উপর সিকিউরিটি সম্পর্কিত কাজগুলি সম্পাদন করে। Spring Security-এর filter chain সাধারণত নিরাপত্তা সংক্রান্ত কাজগুলো (যেমন, authentication, authorization, CSRF protection, session management) পরিচালনা করে। কখনও কখনও, আপনি নির্দিষ্ট কাজের জন্য Custom Filters ব্যবহার করতে চাইবেন, যেমন কাস্টম অথেন্টিকেশন বা লগিং, বিশেষ পরিস্থিতিতে অতিরিক্ত যাচাই করা ইত্যাদি।
Spring Security-তে Custom Filter ব্যবহার করে, আপনি নির্দিষ্ট HTTP রিকোয়েস্টে নিরাপত্তা প্রক্রিয়া বা অতিরিক্ত লজিক যোগ করতে পারেন। Custom filters কাস্টম রিকোয়েস্ট প্রক্রিয়া সম্পাদন করতে ব্যবহৃত হয়, যেমন:
- কাস্টম অথেন্টিকেশন,
- লগিং,
- এক্সট্রা হেডার যাচাই,
- বিশেষ ধরনের CSRF প্রোটেকশন,
- এবং অন্যান্য সিকিউরিটি চেক।
Custom Filter তৈরি করার প্রক্রিয়া
Spring Security-তে Custom Filter তৈরি করার জন্য, আপনি OncePerRequestFilter অথবা GenericFilterBean ব্যবহার করতে পারেন। OncePerRequestFilter একটি খুব সাধারণ ক্লাস, যেটি প্রতিটি রিকোয়েস্টে শুধুমাত্র একবার কার্যকর হয়।
1. Custom Filter তৈরি:
Custom Logging Filter উদাহরণ
এখানে একটি কাস্টম ফিল্টার তৈরি করা হয়েছে যা প্রতিটি HTTP রিকোয়েস্টের আগে লগ মেসেজ প্রিন্ট করবে।
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class CustomLoggingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, javax.servlet.http.HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// লগ ইনফো
String requestURI = request.getRequestURI();
String method = request.getMethod();
System.out.println("Request received: " + method + " " + requestURI);
// পরবর্তী ফিল্টার চেইনে রিকোয়েস্ট পাঠানো
filterChain.doFilter(request, response);
}
}
Explanation:
OncePerRequestFilterইন্টারফেসেরdoFilterInternalমেথডটি কাস্টম ফিল্টারের জন্য অতিরিক্ত লজিক যুক্ত করতে ব্যবহৃত হয়।- এটি প্রতিটি HTTP রিকোয়েস্টের আগে বা পরে আপনার কাস্টম লজিক কার্যকর করতে সাহায্য করে। এখানে কাস্টম লগিং কার্যকলাপটি করা হচ্ছে।
2. Custom Filter কনফিগারেশন:
Spring Security-তে এই কাস্টম ফিল্টারকে যুক্ত করতে আপনাকে ফিল্টার চেইনে এটি ইনজেক্ট করতে হবে। এর জন্য HttpSecurity কনফিগারেশনে addFilterBefore() বা addFilterAfter() পদ্ধতি ব্যবহার করা হয়।
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.addFilterBefore(new CustomLoggingFilter(), UsernamePasswordAuthenticationFilter.class) // ফিল্টারটি ইনজেক্ট করা হচ্ছে
.authorizeRequests()
.antMatchers("/public/**").permitAll() // public URL গুলি নিরাপত্তাহীন
.anyRequest().authenticated(); // সব রিকোয়েস্টের জন্য অথেন্টিকেশন প্রয়োজন
return http.build();
}
}
Explanation:
addFilterBefore()বাaddFilterAfter()পদ্ধতি ব্যবহার করে, আপনি নির্দিষ্ট ফিল্টার চেইনের মধ্যে আপনার কাস্টম ফিল্টার যুক্ত করতে পারেন।- এই উদাহরণে,
CustomLoggingFilterকেUsernamePasswordAuthenticationFilterএর আগে ইনজেক্ট করা হয়েছে, যার মানে হল যে, এটি অন্য সমস্ত নিরাপত্তা ফিল্টার চালানোর আগে কাজ করবে।
3. Custom Filter: Authentication Filter Example
কাস্টম অথেন্টিকেশন ফিল্টার তৈরি করার জন্য, আপনি OncePerRequestFilter ব্যবহার করতে পারেন যা HTTP রিকোয়েস্টে কাস্টম অথেন্টিকেশন যাচাই করবে। এখানে একটি উদাহরণ যেখানে কাস্টম হেডার দিয়ে লগইন যাচাই করা হচ্ছে।
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class CustomAuthFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, javax.servlet.http.HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String authHeader = request.getHeader("X-Custom-Auth");
if (authHeader == null || !authHeader.equals("valid-token")) {
response.setStatus(javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("Unauthorized: Invalid token");
return;
}
// সঠিক অথেন্টিকেশন হলে পরবর্তী ফিল্টার চেইনে প্রক্রিয়া চালিয়ে যাওয়া
filterChain.doFilter(request, response);
}
}
Explanation:
- এই কাস্টম অথেন্টিকেশন ফিল্টারটি রিকোয়েস্টে একটি কাস্টম হেডার (
X-Custom-Auth) চেক করে এবং যদি এটি সঠিক না হয় তবে401 Unauthorizedরেসপন্স ফেরত পাঠায়। - কাস্টম অথেন্টিকেশন যাচাইয়ের জন্য এটি সহজ এবং কার্যকরী উপায়।
4. Custom Filter কনফিগারেশন:
এই কাস্টম অথেন্টিকেশন ফিল্টারকে SecurityConfig-এ কনফিগার করতে হবে। উদাহরণস্বরূপ:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.addFilterBefore(new CustomAuthFilter(), UsernamePasswordAuthenticationFilter.class) // কাস্টম অথেন্টিকেশন ফিল্টার যুক্ত করা হচ্ছে
.authorizeRequests()
.antMatchers("/login").permitAll() // login URL উন্মুক্ত
.anyRequest().authenticated(); // অন্যান্য রিকোয়েস্টে অথেন্টিকেশন প্রয়োজন
return http.build();
}
}
Explanation:
CustomAuthFilterফিল্টারটিUsernamePasswordAuthenticationFilterএর আগে যুক্ত করা হয়েছে, যার মানে এটি ব্যবহারকারীর লগইন তথ্য যাচাই করার আগে কাস্টম অথেন্টিকেশন ফিল্টার কাজ করবে।
Spring Security-তে Custom Filters ব্যবহারের সুবিধা
- বিশেষ ফিল্টার লজিক: আপনি যেকোনো বিশেষ সিকিউরিটি চেক বা কার্যকলাপ কাস্টম ফিল্টারে সংযুক্ত করতে পারেন, যেমন কাস্টম অথেন্টিকেশন, লগিং, কাস্টম হেডার যাচাই ইত্যাদি।
- ফিল্টার চেইন কাস্টমাইজেশন: Spring Security এর ডিফল্ট ফিল্টার চেইন আপনার নির্দিষ্ট প্রয়োজন অনুযায়ী কাস্টমাইজ করা যায়, যেমন একটি নির্দিষ্ট ফিল্টার আগে বা পরে আপনার কাস্টম ফিল্টার যুক্ত করা।
- প্রতিটি রিকোয়েস্টে কাজ করা:
OncePerRequestFilterফিল্টারটি প্রতি HTTP রিকোয়েস্টে একবার কার্যকরী হয়, যা কাস্টম লগিক বা সিকিউরিটি যাচাই সহজভাবে সম্পাদন করতে দেয়। - অতিরিক্ত নিরাপত্তা স্তর: কাস্টম ফিল্টার ব্যবহারের মাধ্যমে আপনি অতিরিক্ত নিরাপত্তা যাচাই করতে পারেন, যেমন ইনপুট ভ্যালিডেশন, কাস্টম অথেন্টিকেশন, CSRF যাচাই ইত্যাদি।
উপসংহার
Spring Security-তে Custom Filters একটি অত্যন্ত শক্তিশালী এবং নমনীয় উপায়, যার মাধ্যমে আপনি অ্যাপ্লিকেশনগুলির জন্য নির্দিষ্ট সিকিউরিটি চেক এবং অতিরিক্ত লজিক সংযুক্ত করতে পারেন। এটি বিশেষভাবে ব্যবহারকারীর অথেন্টিকেশন এবং অন্যান্য নিরাপত্তা চেক কাস্টমাইজ করার জন্য উপযুক্ত।
Spring Security এ Custom Filter তৈরি করার মাধ্যমে আপনি সিকিউরিটি চেক বা কাস্টম প্রক্রিয়াগুলি আপনার ওয়েব অ্যাপ্লিকেশনে সংযোজন করতে পারেন। Spring Security বিভিন্ন ফিল্টার ব্যবহার করে HTTP রিকোয়েস্টের নিরাপত্তা নিশ্চিত করে, এবং আপনি আপনার প্রয়োজনে একটি কাস্টম ফিল্টার তৈরি করতে পারেন যা নির্দিষ্ট রিকোয়েস্টের জন্য নিরাপত্তা যাচাই বা অন্যান্য কাজ সম্পাদন করবে।
ফিল্টারগুলি সাধারণত Filter Chain এ একের পর এক চলে এবং রিকোয়েস্ট প্রক্রেস করার জন্য বিভিন্ন কাজ সম্পন্ন করে।
Custom Filter তৈরির ধাপসমূহ
1. Filter Interface Implement করা
স্প্রিং সিকিউরিটিতে কাস্টম ফিল্টার তৈরি করতে হলে javax.servlet.Filter বা org.springframework.web.filter.GenericFilterBean ইন্টারফেস ইমপ্লিমেন্ট করতে হবে। সাধারনত, GenericFilterBean ব্যবহার করা হয় কারণ এটি স্প্রিং-এর কনটেক্সটের সাথে ভালোভাবে কাজ করে।
2. FilterBean কনফিগার করা
এই ফিল্টারটি স্প্রিং সিকিউরিটি কনফিগারেশনের অংশ হিসেবে যুক্ত করতে হবে।
Custom Filter তৈরি করার উদাহরণ
ধরা যাক, আমরা একটি কাস্টম ফিল্টার তৈরি করতে চাই যা প্রতিটি রিকোয়েস্টে একটি কাস্টম হেডার চেক করবে এবং যদি এটি না থাকে, তবে রিকোয়েস্টটি ব্লক করবে।
1. Custom Filter তৈরি করা
প্রথমে, একটি কাস্টম ফিল্টার তৈরি করি যা চেক করবে যে রিকোয়েস্টে একটি নির্দিষ্ট হেডার আছে কি না। যদি না থাকে, তবে 403 Forbidden রেসপন্স ফিরিয়ে দিবে।
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CustomHeaderFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// চেক করুন হেডারে একটি নির্দিষ্ট ভ্যালু আছে কি না
String header = httpRequest.getHeader("X-Custom-Header");
if (header == null || !header.equals("expectedValue")) {
// যদি হেডারটি নেই বা সঠিক না হয়, তাহলে 403 ফিরিয়ে দিন
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden: Invalid Header");
return;
}
// যদি হেডার সঠিক থাকে, তাহলে চেইন চালিয়ে যান
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Custom filter initialization (if needed)
}
@Override
public void destroy() {
// Cleanup if needed
}
}
2. Custom Filter Spring Security Configurations এ রেজিস্টার করা
এখন আমাদের এই কাস্টম ফিল্টারটি Spring Security কনফিগারেশনে রেজিস্টার করতে হবে যাতে এটি রিকোয়েস্ট প্রক্রেসিংয়ের অংশ হিসেবে কাজ করে।
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// কাস্টম ফিল্টারটি স্প্রিং সিকিউরিটি ফিল্টার চেইনে যুক্ত করুন
http.addFilterBefore(new CustomHeaderFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
.antMatchers("/public/**").permitAll() // Public URL access
.anyRequest().authenticated() // All other URLs need authentication
.and()
.formLogin() // Enable form-based login
.and()
.logout(); // Enable logout functionality
}
}
এখানে addFilterBefore মেথডটি ব্যবহার করা হয়েছে যা কাস্টম ফিল্টারটি UsernamePasswordAuthenticationFilter এর আগে সিকিউরিটি ফিল্টার চেইনে যুক্ত করবে। আপনি চাইলে addFilterAfter ব্যবহার করতে পারেন যাতে এটি অন্য কোনো ফিল্টারের পরে চলে।
3. FilterChainConfigurer - ফিল্টারের অর্ডার এবং কাস্টম কনফিগারেশন
যদি আপনার অ্যাপ্লিকেশনটিতে একাধিক কাস্টম ফিল্টার থাকে, তবে সেগুলোর কাজের অর্ডার নির্ধারণ করা খুবই গুরুত্বপূর্ণ। আপনি চাইলে ফিল্টারগুলির মধ্যে একটি নির্দিষ্ট অর্ডারও সেট করতে পারেন।
http.addFilterBefore(new CustomFilterOne(), UsernamePasswordAuthenticationFilter.class);
http.addFilterAfter(new CustomFilterTwo(), CustomFilterOne.class);
এখানে, CustomFilterOne প্রথমে চলে এবং তারপর CustomFilterTwo চলে।
4. Filter Bean Lifecycle
যতটা সম্ভব ফিল্টারের জীবনচক্র (Lifecycle) স্পষ্টভাবে ব্যাখ্যা করা উচিত, কারণ Spring এর GenericFilterBean ক্লাসে init() এবং destroy() মেথড থাকে, যা আপনি ফিল্টারের ইনিশিয়ালাইজেশন এবং ক্লিনআপের জন্য ব্যবহার করতে পারেন।
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Filter initialization logic
}
@Override
public void destroy() {
// Filter cleanup logic
}
5. কাস্টম ফিল্টারের নিরাপত্তা ভূমিকা
Spring Security ফিল্টার চেইনে কাস্টম ফিল্টার যোগ করার মাধ্যমে আপনি:
- এনক্রিপশন চেক: রিকোয়েস্টের ডেটা সুরক্ষিত কিনা তা যাচাই করতে পারেন।
- অনুমতি যাচাই: বিশেষ রোল বা অনুমতি যাচাই করার জন্য কাস্টম লজিক প্রয়োগ করতে পারেন।
- লগিং এবং মনিটরিং: কাস্টম ফিল্টার দিয়ে রিকোয়েস্ট লগ বা মনিটর করতে পারেন।
- ক্রস-সাইট স্ক্রিপ্টিং (XSS) প্রতিরোধ: স্পষ্টভাবে স্ক্রিপ্ট ইনপুট ফিল্টারিং করতে পারেন।
উপসংহার
স্প্রিং সিকিউরিটির কাস্টম ফিল্টার তৈরি করার মাধ্যমে আপনি নিরাপত্তা সম্পর্কিত বিভিন্ন কাস্টম চেক বা লজিক অ্যাপ্লিকেশনে প্রয়োগ করতে পারেন। এটি স্প্রিং সিকিউরিটির ফিল্টার চেইনে আপনার নির্দিষ্ট নিরাপত্তা নীতি বা অন্যান্য ফিচার যোগ করার জন্য একটি শক্তিশালী মাধ্যম।
Spring Security তে OncePerRequestFilter এবং GenericFilterBean দুটি ক্লাস হল ফিল্টার যা HTTP অনুরোধের প্রক্রিয়াকরণের সময় কাস্টম ফিল্টার যুক্ত করতে ব্যবহৃত হয়। এগুলো সাধারণত বিশেষভাবে কাস্টম অথেন্টিকেশন, অথোরাইজেশন, লগিং, বা অন্যান্য নিরাপত্তা বৈশিষ্ট্য বাস্তবায়ন করতে ব্যবহৃত হয়।
OncePerRequestFilter
OncePerRequestFilter হল একটি abstract ক্লাস যা Spring Security এবং অন্যান্য Spring-ভিত্তিক অ্যাপ্লিকেশনে ফিল্টার ব্যবহার করার জন্য অত্যন্ত উপকারী। এর মূল সুবিধা হল যে এটি শুধুমাত্র একটি নির্দিষ্ট HTTP অনুরোধের জন্য একবার কার্যকর হয়, যাতে একাধিক ফিল্টার একসাথে একই রিকোয়েস্ট প্রক্রিয়াকরণ না করে।
কীভাবে কাজ করে:
OncePerRequestFilter একটি রিকোয়েস্টের জন্য একবার কাস্টম ফিল্টার চলবে, যা সাধারণত ফিল্টার চেইনে সঠিক সময়ে চালানো হয়। এটি doFilterInternal মেথডে কাস্টম লজিক রচনা করতে দেয়, যেখানে অনুরোধের প্রক্রিয়া নিয়ন্ত্রণ করা হয়।
OncePerRequestFilter ব্যবহার করার উদাহরণ:
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.filter.Filter;
import org.springframework.web.util.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class CustomOncePerRequestFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// Filter logic here (For example, logging or authentication checks)
String userAgent = request.getHeader("User-Agent");
System.out.println("User-Agent: " + userAgent);
// Pass the request along the filter chain
filterChain.doFilter(request, response);
}
}
SecurityConfig এ OncePerRequestFilter কনফিগার করা:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.addFilterBefore(new CustomOncePerRequestFilter(), OncePerRequestFilter.class)
.authorizeRequests()
.anyRequest().authenticated();
return http.build();
}
}
এখানে addFilterBefore ব্যবহার করে আমরা OncePerRequestFilter ফিল্টারটিকে Spring Security ফিল্টার চেইনে যোগ করেছি। এটি একটি নির্দিষ্ট ফিল্টারের আগে বা পরে চলতে পারে (যেমন OncePerRequestFilter.class এখানে ব্যবহার করা হয়েছে)।
GenericFilterBean
GenericFilterBean একটি সিম্পল Spring Bean যা একটি কাস্টম ফিল্টার তৈরি করতে ব্যবহৃত হয়। এটি javax.servlet.Filter ইন্টারফেস বাস্তবায়ন করে এবং সাধারণত অতিরিক্ত লজিক এবং ফিল্টারিং ফিচারের জন্য ব্যবহৃত হয়।
কীভাবে কাজ করে:
GenericFilterBean এর মাধ্যমে আপনি নিজস্ব কাস্টম ফিল্টার তৈরি করতে পারেন যা doFilter মেথডে অনুরোধ প্রক্রিয়া করার সময় অতিরিক্ত লজিক প্রয়োগ করতে দেয়।
GenericFilterBean ব্যবহার করার উদাহরণ:
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class CustomGenericFilterBean extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// Custom filter logic (Example: logging)
System.out.println("Request received: " + request.getRemoteAddr());
// Continue the request-response chain
chain.doFilter(request, response);
}
}
SecurityConfig এ GenericFilterBean কনফিগার করা:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.addFilterBefore(new CustomGenericFilterBean(), GenericFilterBean.class)
.authorizeRequests()
.anyRequest().authenticated();
return http.build();
}
}
এখানে addFilterBefore ব্যবহার করে আমরা CustomGenericFilterBean ফিল্টারটিকে Spring Security ফিল্টার চেইনে যুক্ত করেছি।
OncePerRequestFilter vs GenericFilterBean: পার্থক্য
| বৈশিষ্ট্য | OncePerRequestFilter | GenericFilterBean |
|---|---|---|
| নির্ধারণ | শুধুমাত্র একবার ফিল্টার চালানো হয়। | সাধারণ ফিল্টার যা অনুরোধ প্রক্রিয়া চলাকালীন একাধিক বার চলতে পারে। |
| কাস্টম ফিল্টারিং | প্রক্রিয়া একবার হবে। (উদাহরণস্বরূপ, রিকোয়েস্টের উপর একক চেক) | অনুরোধের প্রতি বার ফিল্টারিং চালানো যায়। |
| ব্যবহার | এক্সপেনশন প্রয়োজন যেখানে আপনি একবার একটি রিকোয়েস্ট প্রক্রিয়া করতে চান। | সাধারণ ফিল্টার লগিকের জন্য, যেমন লগিং বা জটিল কাস্টম প্রক্রিয়াকরণ। |
কেন OncePerRequestFilter এবং GenericFilterBean ব্যবহার করবেন?
OncePerRequestFilter: এটি ব্যবহার করা হয় যখন আপনি একটি অনুরোধের জন্য একবার কাস্টম ফিল্টার চালাতে চান (যেমন লগিং, সেশন ম্যানেজমেন্ট বা অন্যান্য নিরাপত্তা যাচাই)। এটি ফিল্টার চেইনের একটি নির্দিষ্ট স্থানে একবার চলবে, যা সাধারণত অথেন্টিকেশন বা অথোরাইজেশন ফিল্টারের আগে ব্যবহৃত হয়।GenericFilterBean: এটি সাধারণ কাস্টম ফিল্টারের জন্য উপযুক্ত। আপনি যখন আরও জটিল লগিক বা একাধিক ফিল্টারিং চালাতে চান এবং একাধিক বার ফিল্টার প্রয়োগ করতে চান তখন এটি ব্যবহার করা হয়।
উপসংহার
OncePerRequestFilter এবং GenericFilterBean Spring Security এবং Spring Framework এ কাস্টম ফিল্টারিং প্রক্রিয়া পরিচালনার জন্য অত্যন্ত শক্তিশালী উপায়। OncePerRequestFilter একক অনুরোধের জন্য একবার ফিল্টার চালানোর জন্য উপযুক্ত, যেখানে GenericFilterBean এর মাধ্যমে আপনি আরও জটিল বা একাধিক ফিল্টারিং প্রক্রিয়া করতে পারেন।
স্প্রিং সিকিউরিটিতে Custom Authentication এবং Custom Authorization ফিল্টার তৈরি করা সম্ভব, যা আপনার নির্দিষ্ট নিরাপত্তা নীতির উপর ভিত্তি করে কাজ করতে পারে। এই ফিল্টারগুলি আপনাকে বিশেষভাবে ক্লায়েন্টের অনুরোধের উপর কাস্টম অথেনটিকেশন এবং অথরাইজেশন চেক করার অনুমতি দেয়।
এখানে আমরা Custom Authentication Filter এবং Custom Authorization Filter তৈরি করার একটি উদাহরণ দেখব এবং কিভাবে এগুলি স্প্রিং সিকিউরিটির সিকিউরিটি কনফিগারেশনে যুক্ত করা যায় তা দেখানো হবে।
১. Custom Authentication Filter
Custom Authentication Filter তৈরি করার মাধ্যমে, আপনি নিজের প্রয়োজন অনুযায়ী HTTP অনুরোধ থেকে ইউজারের অথেনটিকেশন হ্যান্ডেল করতে পারেন। সাধারণত JWT (JSON Web Token) বা কোনো কাস্টম অথেনটিকেশন স্কিমা ব্যবহার করে এফিল্টার কাজ করে।
Step 1: Custom Authentication Filter তৈরি করুন
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class CustomAuthenticationFilter extends OncePerRequestFilter {
private final AuthenticationManager authenticationManager;
public CustomAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
protected void doFilterInternal(HttpServletRequest request, javax.servlet.FilterChain chain)
throws ServletException, IOException {
String token = request.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
String jwt = token.substring(7); // Extract JWT token
// Normally here, you would parse and validate the JWT token to get the user details
String username = "extracted_username_from_jwt"; // Example: extracted from JWT
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(username, null, null); // Use roles if needed
Authentication authentication = authenticationManager.authenticate(authenticationToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
chain.doFilter(request, response);
}
}
ব্যাখ্যা:
OncePerRequestFilter: এটি স্প্রিং সিকিউরিটির একটি বেস ক্লাস যা একবারে একবার একটি রিকোয়েস্ট প্রসেস করে।- JWT: এখানে আমরা ধরে নিয়েছি যে আপনি JWT টোকেন থেকে ইউজারের নাম সংগ্রহ করছেন, তবে এটি যেকোনো ধরনের কাস্টম অথেনটিকেশন হতে পারে (যেমন, ইউজারনেম-পাসওয়ার্ড, API কিওয়া ইত্যাদি)।
AuthenticationManager: এটি একটি ইন্টারফেস যা ইউজারের অথেনটিকেশন নিশ্চিত করে।
Step 2: Security Configuration এ Filter যোগ করা
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final AuthenticationManager authenticationManager;
public SecurityConfig(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilter(new CustomAuthenticationFilter(authenticationManager)) // Add custom authentication filter
.authorizeRequests()
.antMatchers("/public/**").permitAll() // Public access endpoints
.anyRequest().authenticated(); // All other requests need authentication
}
}
২. Custom Authorization Filter
Custom Authorization Filter তৈরি করার মাধ্যমে, আপনি নিশ্চিত করতে পারেন যে শুধুমাত্র অনুমোদিত ইউজাররা বিশেষ রিসোর্সে অ্যাক্সেস পাবে। এটি সাধারণত Role-based বা Permission-based অ্যাক্সেস কন্ট্রোল ইমপ্লিমেন্ট করতে ব্যবহৃত হয়।
Step 1: Custom Authorization Filter তৈরি করুন
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class CustomAuthorizationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, javax.servlet.FilterChain chain)
throws ServletException, IOException {
Authentication authentication = (Authentication) SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
// Here you can implement your authorization logic
// For example: check if the user has required roles/permissions to access the resource
if (!hasPermission(authentication, request.getRequestURI())) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "You do not have permission to access this resource");
return;
}
}
chain.doFilter(request, response);
}
// Example permission check (this can be customized based on your needs)
private boolean hasPermission(Authentication authentication, String uri) {
// Check user roles/permissions
if (authentication.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_ADMIN"))) {
return true; // If the user has ADMIN role, grant access
}
return false; // Otherwise, deny access
}
}
ব্যাখ্যা:
OncePerRequestFilter: এটি প্রতি HTTP অনুরোধের জন্য একবার চালিত হয়।hasPermission: একটি উদাহরণ ফাংশন যেখানে আপনি ব্যবহারকারীর রোল বা পারমিশন যাচাই করতে পারেন।response.sendError(HttpServletResponse.SC_FORBIDDEN, "You do not have permission to access this resource");: যদি ব্যবহারকারীর অনুমতি না থাকে, তাহলে তাকে 403 Forbidden ত্রুটি পাঠানো হয়।
Step 2: Security Configuration এ Authorization Filter যোগ করা
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilter(new CustomAuthorizationFilter()) // Add custom authorization filter
.authorizeRequests()
.antMatchers("/public/**").permitAll() // Public access endpoints
.anyRequest().authenticated(); // All other requests need authentication
}
}
৩. কাস্টম অথেনটিকেশন এবং অথরাইজেশন ফিল্টার ব্যবহার করার উপকারিতা:
- কাস্টম অথেনটিকেশন:
- আপনার নিজের অথেনটিকেশন পদ্ধতি ব্যবহার করে ইউজারের পরিচয় যাচাই করতে পারবেন।
- উদাহরণস্বরূপ, JWT, OAuth, বা অন্য কোনো কাস্টম অথেনটিকেশন স্কিমা।
- কাস্টম অথরাইজেশন:
- ইউজারের রোল বা পারমিশন যাচাই করে অ্যাক্সেস কন্ট্রোল করতে পারবেন।
- আপনি বিভিন্ন রিসোর্স বা API এ একাধিক রোল বা পারমিশন যাচাই করতে পারেন, যেমন
ROLE_ADMINবাWRITE_PERMISSION।
- নিরাপত্তা:
- আপনার নিরাপত্তা নীতির সাথে সঙ্গতিপূর্ণ কাস্টম অথেনটিকেশন এবং অথরাইজেশন পদ্ধতি তৈরি করতে পারবেন।
- এটি ইউজারের অ্যাক্সেস নিয়ন্ত্রণে আরও সূক্ষ্মতা এবং নমনীয়তা এনে দেয়।
উপসংহার
স্প্রিং সিকিউরিটিতে Custom Authentication Filter এবং Custom Authorization Filter তৈরি করা খুবই কার্যকরী এবং শক্তিশালী নিরাপত্তা ব্যবস্থা। কাস্টম অথেনটিকেশন ফিল্টার ইউজারের পরিচয় যাচাই করে, এবং কাস্টম অথরাইজেশন ফিল্টার ইউজারের অনুমতি যাচাই করে। আপনি যেভাবে চাচ্ছেন আপনার নিরাপত্তা নিয়ন্ত্রণ ব্যবস্থা সেটআপ করতে পারবেন, এবং এটি স্প্রিং সিকিউরিটির স্ট্যান্ডার্ড নিরাপত্তা ফিচারের সাথে একত্রে কাজ করবে।
Spring Security তে Custom Filter তৈরি করা একটি শক্তিশালী পদ্ধতি যা আপনার নিরাপত্তা প্রক্রিয়াতে নির্দিষ্ট কাজ যেমন লগিং, অথেনটিকেশন চেক, অথরাইজেশন বা কাস্টম লজিক যোগ করতে সহায়ক। Spring Security-তে Custom Filter বাস্তবায়ন করতে হলে, আপনাকে OncePerRequestFilter বা Filter ইন্টারফেস ইমপ্লিমেন্ট করতে হবে।
এখানে Custom Filter তৈরি করার একটি উদাহরণ দেয়া হয়েছে, যেখানে আমরা একটি কাস্টম অথেনটিকেশন ফিল্টার তৈরি করব যা প্রতি অনুরোধের সাথে ইউজারনেম এবং পাসওয়ার্ড যাচাই করবে।
Custom Filter তৈরি করার ধাপ:
Step 1: Maven Dependency
প্রথমে আপনার pom.xml ফাইলে Spring Security ডিপেন্ডেন্সি যোগ করুন, যদি আপনি এটি ইতোমধ্যে যোগ না করে থাকেন।
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Step 2: Custom Filter তৈরি করা
এখন, আমরা একটি Custom Filter তৈরি করব যা প্রতিটি HTTP অনুরোধের জন্য ইউজারনেম এবং পাসওয়ার্ড যাচাই করবে।
package com.example.security;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CustomAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// Extract the username and password from request headers or parameters
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username != null && password != null) {
// Custom Authentication logic
if (authenticateUser(username, password)) {
// If authentication is successful, set the user authentication in the SecurityContext
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(username, password));
} else {
// If authentication fails, return unauthorized response
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
}
// Continue with the filter chain
filterChain.doFilter(request, response);
}
// Custom user authentication method
private boolean authenticateUser(String username, String password) {
// Simple hardcoded authentication logic (you can replace this with actual authentication)
return "user".equals(username) && "password123".equals(password);
}
}
Explanation:
OncePerRequestFilter: Spring Framework থেকে একটি বেস ক্লাস যা প্রতি রিকোয়েস্টে একবার ফিল্টার চালানোর গ্যারান্টি দেয়।doFilterInternal(): এই মেথডে আপনি কাস্টম লজিক ব্যবহার করতে পারেন যা প্রতিটি HTTP অনুরোধের জন্য কার্যকর হবে।authenticateUser(): এখানে আপনি আপনার কাস্টম অথেনটিকেশন লজিক দিতে পারেন। এই উদাহরণে আমরা সোজাসুজিusernameএবংpasswordযাচাই করেছি, তবে এখানে ডাটাবেস বা অন্য সিস্টেমের সাথে ইন্টিগ্রেশন করা সম্ভব।SecurityContextHolder.getContext().setAuthentication(): যদি ব্যবহারকারী সফলভাবে অথেনটিকেট হয়, তবে এটিSecurityContextএ ব্যবহারকারীর তথ্য সেট করে, যাতে পরবর্তী রিকোয়েস্টে Spring Security এর নিরাপত্তা ব্যবস্থাপনা করতে পারে।
Step 3: Custom Filter কনফিগারেশন
এখন আমাদের কাস্টম ফিল্টারকে Spring Security কনফিগারেশন ক্লাসে রেজিস্টার করতে হবে।
package com.example.config;
import com.example.security.CustomAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.addFilterBefore(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) // Add custom filter
.authorizeRequests()
.antMatchers("/public/**").permitAll() // Public endpoints
.anyRequest().authenticated() // All other requests require authentication
.and()
.formLogin(); // Enable form login
return http.build();
}
@Bean
public CustomAuthenticationFilter customAuthenticationFilter() {
return new CustomAuthenticationFilter();
}
}
Explanation:
addFilterBefore(): এটি Spring Security এরUsernamePasswordAuthenticationFilterএর আগে আমাদের কাস্টম ফিল্টারটি চালানোর জন্য ব্যবহৃত হয়। এর মানে হল যে, আমাদের কাস্টম ফিল্টারটিUsernamePasswordAuthenticationFilterএর আগে চলে আসবে এবং এটি সব রিকোয়েস্টের জন্য কার্যকর হবে।antMatchers("/public/**").permitAll():/public/**এর মতো পাবলিক রিসোর্সগুলো কাউকে অথেনটিকেট করতে হবে না।.anyRequest().authenticated(): অন্য সব রিকোয়েস্টের জন্য ব্যবহারকারীকে অথেনটিকেট করা প্রয়োজন।
Step 4: Testing Custom Filter
এখন, আপনার কাস্টম ফিল্টারটি সঠিকভাবে কাজ করছে কিনা তা পরীক্ষা করতে, আপনি একটি HTTP রিকোয়েস্ট পাঠাতে পারেন:
Example Request:
POST /login HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=user&password=password123
- যদি ইউজারনেম এবং পাসওয়ার্ড সঠিক হয়, তবে রিকোয়েস্টটি সফলভাবে প্রসেস হবে এবং SecurityContext এ ব্যবহারকারীর তথ্য সেট হবে।
- যদি ইউজারনেম বা পাসওয়ার্ড ভুল হয়, তবে 401 Unauthorized রেসপন্স ফেরত দেওয়া হবে।
Conclusion
Spring Security তে Custom Filter বাস্তবায়ন করার মাধ্যমে আপনি আপনার নিরাপত্তা ব্যবস্থাপনা আরও কাস্টমাইজ করতে পারেন। এটি বিশেষত তখন কার্যকরী যখন আপনি নির্দিষ্ট লজিক বা ফিচার যোগ করতে চান যা Spring Security-এর ডিফল্ট ফিল্টারস দ্বারা সরাসরি সমর্থিত নয়, যেমন কাস্টম অথেনটিকেশন বা অথরাইজেশন চেক। Custom Filters সহজেই Spring Security কনফিগারেশনে যোগ করা যায় এবং আপনার অ্যাপ্লিকেশনের নিরাপত্তা চাহিদা অনুযায়ী কাস্টমাইজ করা যায়।
Read more